import KRect from '@kernel/util/rect'
import {RectAttackEndCallback, RectAttackMonsterCallback} from '@kernel/lib/attack/types'
import KUnit from '@kernel/util/unit'
import KPlayer from '@kernel/util/player'

/**
 * 刷兵系统
 */
export default class RectAttack {
  /**
   * 出怪点是否随机
   * @private
   */
  private isRandom = false;

  /**
   * 进攻点
   * @private
   */
  private target: Vector3|null;

  /**
   * 出兵间隔
   * @private
   */
  private monsterInterval = 1;

  /**
   * 计时器
   * @private
   */
  private timerId = 0

  /**
   * 当前出兵数量
   */
  public monsterNumber = 0

  /**
   * 刷兵区域
   * @private
   */
  private rects: KRect[] = [];

  /**
   * 结束回调
   * @private
   */
  private endCallbacks: RectAttackEndCallback[] = []

  /**
   * 出兵回调
   * @private
   */
  private refreshCallbacks: RectAttackMonsterCallback[] = []

  /**
   * @param player 玩家
   * @param monsterId 兵种id
   * @param monsterCount 每个区域刷兵数量
   */
  constructor(private player: KPlayer, private monsterId: number, private monsterCount: number) {
  }

  /**
   * 增加刷怪区域
   * @param rect
   */
  addRect(rect: KRect) {
    this.rects.push(rect)
  }

  /**
   * 设置刷怪区域随机点
   * @param value
   */
  setIsRandom(value: boolean) {
    this.isRandom = value
  }

  /**
   * 设置进攻点
   * @param x
   * @param y
   */
  setTarget(x: number, y: number) {
    this.target = Fix32Vec3(x, y, 0)
    return this
  }

  /**
   * 设置出兵间隔
   * @param value
   */
  setMonsterInterval(value: number) {
    this.monsterInterval = value
    return this
  }

  /**
   * 监听刷兵结束
   * @param callback
   */
  onEnd(callback: RectAttackEndCallback) {
    this.endCallbacks.push(callback)
    return this
  }

  /**
   * 出兵回调
   * @param callback
   */
  onRefresh(callback: RectAttackMonsterCallback) {
    this.refreshCallbacks.push(callback)
    return this
  }

  /**
   * 开始
   */
  start() {
    this.timerId = setInterval(() => {
      this.rects.forEach(rect => {
        const point = this.getRefreshPoint(rect)
        const unit = KUnit.create(this.player, this.monsterId, point)
        if (this.target) {
          unit.releaseCommand('attackMove', this.target)
        }
        this.refreshCallbacks.forEach(call => call(unit, point))
      })
      if (this.monsterNumber >= this.monsterCount) {
        this.endCallbacks.forEach(callback => callback())
        clearInterval(this.timerId)
      }
    }, this.monsterInterval * 1000)
  }

  /**
   * 获取刷怪点
   * @param rect
   * @private
   */
  private getRefreshPoint(rect: KRect): FVector3 {
    if (this.isRandom) {
      return rect.random()
    }
    return rect.center()
  }
}
